package com.unis.common.handler;

import com.alibaba.fastjson.JSON;
import com.unis.common.util.WebUtil;
import com.unis.logger.TargetLogger;
import com.unis.model.system.SysLog;
import com.unis.service.system.SysLogMetaService;
import com.unis.service.system.SysLogService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.codec.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created by Administrator on 2019/1/8/008.
 */
public class GlobalInterceptHandler extends HandlerInterceptorAdapter {
    final Logger logger = LoggerFactory.getLogger(GlobalInterceptHandler.class);
    @Autowired
    private SysLogService sysLogService;
    @Autowired
    private SysLogMetaService sysLogMetaService;

    private static final int SESSION_INVALID_CODE = 999;

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        //日志记录
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            //获取是否有@TargetLogger注解
            TargetLogger targetLogger = handlerMethod.getMethodAnnotation(TargetLogger.class);
            if (targetLogger != null && StringUtils.isNotBlank(targetLogger.value())) {
                logger.debug("操作代码：" + targetLogger.value());//注解中的操作代码
                String targetName = handlerMethod.getBean().getClass().toString();//类
                String methodName = handlerMethod.getMethod().getName();//方法名称
                String ip = getIpAddr(request);

                Map<String, String[]> pramMap = request.getParameterMap();

                Map<String, String[]> prams = new HashMap<>();
                Set<String> keySet = pramMap.keySet();
                for (String key : keySet) {
                    if (StringUtils.equalsIgnoreCase(targetLogger.value(), "0101") && StringUtils.equalsIgnoreCase("password", key)) {
                        prams.put(key, new String[]{Base64.encodeToString((pramMap.get(key)[0]).getBytes())});
                    } else {
                        prams.put(key, pramMap.get(key));
                    }
                }

                String czdata = prams != null && !prams.isEmpty() ? JSON.toJSONString(prams) : "";

                Map<String, String> logMetas = sysLogMetaService.queryAllLogMeta();
                String czdetail = logMetas != null && !logMetas.isEmpty() ? logMetas.get(targetLogger.value()) : "";
                logger.debug("操作名称：" + czdetail);//注解中的操作代码对应操作
                SysLog log = new SysLog();
                log.setCzbm(targetLogger.value());
                log.setCzdetail(czdetail);
                log.setCzdata(StringUtils.length(czdata) > 2000 ? StringUtils.substring(czdata, 0, 2000) : czdata);
                log.setCzip(ip);
                if (ex != null) {
                    if (ex instanceof UnauthorizedException) {
                        logger.error("用户角色错误: " + ex.getMessage());
                        throw new Exception("用户角色错误");
                    }
                    log.setFlag((short) 0);
                    log.setErrdetail(StringUtils.isNotBlank(ex.getMessage()) ? StringUtils.length(ex.getMessage()) > 2000 ? StringUtils.substring(ex.getMessage(), 0, 2000) : "" : "");
                } else {
                    log.setFlag((short) 1);
                }
                log.setReqmethod((targetName + "." + methodName + "()"));
                //保存数据库
                sysLogService.insert(log);
            }
        }
        super.afterCompletion(request, response, handler, ex);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.info("发起请求: {}", request.getRequestURI());
        }
        if (WebUtil.isAjax(request) && request.getServletPath().indexOf("login") != -1) {
            response.setStatus(SESSION_INVALID_CODE);
            logger.warn("session已经失效, 请重新登录!");
        }
        return super.preHandle(request, response, handler);
    }

    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("x-forwarded-for");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
